Skip to content

Conversation

nielsdos
Copy link
Member

The "else branch" of next_line can reset the buf_begin field to NULL, causing the next invocation to pass NULL to memchr with a 0 length. When UBSAN is enabled this causes an UBSAN abort. Real world impact is likely none because of the 0 length.

To fix this, don't set the pointer to NULL, which means that the memchr will return NULL and since
self->bytes_in_buffer < self->bufsize we return NULL and request more data through fill_buffer. That function will reset buf_begin and bytes_in_buffer so that the next invocation works fine.

I chose this solution so we have an invariant that buf_begin is never NULL, which makes reasoning easier. An alternative solution is keeping the NULLing of buf_begin and add an extra check at the top of next_line, but I didn't like special casing this.

The "else branch" of `next_line` can reset the `buf_begin` field to
NULL, causing the next invocation to pass NULL to `memchr` with a 0
length. When UBSAN is enabled this causes an UBSAN abort. Real world
impact is likely none because of the 0 length.

To fix this, don't set the pointer to NULL, which means that the
`memchr` will return NULL and since
`self->bytes_in_buffer < self->bufsize` we return NULL and request more
data through `fill_buffer`. That function will reset `buf_begin` and
`bytes_in_buffer` so that the next invocation works fine.

I chose this solution so we have an invariant that `buf_begin` is never
NULL, which makes reasoning easier. An alternative solution is keeping
the NULLing of `buf_begin` and add an extra check at the top of
`next_line`, but I didn't like special casing this.
@nielsdos nielsdos requested a review from arnaud-lb November 30, 2024 11:33
@nielsdos nielsdos requested a review from bukka as a code owner November 30, 2024 11:33
@nielsdos nielsdos linked an issue Nov 30, 2024 that may be closed by this pull request
Copy link
Member

@arnaud-lb arnaud-lb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Thank you!

@nielsdos nielsdos closed this in aab7842 Dec 1, 2024
charmitro pushed a commit to wasix-org/php that referenced this pull request Mar 13, 2025
The "else branch" of `next_line` can reset the `buf_begin` field to
NULL, causing the next invocation to pass NULL to `memchr` with a 0
length. When UBSAN is enabled this causes an UBSAN abort. Real world
impact is likely none because of the 0 length.

To fix this, don't set the pointer to NULL, which means that the
`memchr` will return NULL and since
`self->bytes_in_buffer < self->bufsize` we return NULL and request more
data through `fill_buffer`. That function will reset `buf_begin` and
`bytes_in_buffer` so that the next invocation works fine.

I chose this solution so we have an invariant that `buf_begin` is never
NULL, which makes reasoning easier. An alternative solution is keeping
the NULLing of `buf_begin` and add an extra check at the top of
`next_line`, but I didn't like special casing this.

Closes phpGH-17000.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UBSAN warning in rfc1867

2 participants